<%@ page language="java" import="net.sf.json.JSONObject" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ page import="org.apache.commons.fileupload.FileItem" %>
<%@ page import="org.apache.commons.lang.StringUtils" %>
<%@ page import="up7.biz.PathBuilder" %>
<%@ page import="up7.biz.WebSafe" %>
<%@ page import="up7.biz.up7_biz_event" %>
<%@ page import="up7.model.FileInf" %>
<%@ page import="up7.utils.*" %>
<%@ page import="java.io.ByteArrayOutputStream" %>
<%
	out.clear();
	/*
		此页面负责将文件块数据写入文件中。
		此页面一般由控件负责调用
		参数：
			uid
			idSvr
			md5
			lenSvr
			RangePos
			fd_idSvr
			fd_lenSvr
		更新记录：
			2017-10-23 删除文件块缓存
			2017-08-15 精简和优化代码
			2017-05-14 优化参数传递方式，改为使用head方式传递参数
			2016-04-09 优化文件存储逻辑，增加更新文件夹进度逻辑
			2014-07-23 优化代码。
			2012-10-25 整合更新文件进度信息功能。减少客户端的AJAX调用。
			2012-04-18 取消更新文件上传进度信息逻辑。
			2012-04-12 更新文件大小变量类型，增加对2G以上文件的支持。

	*/

	WebBase wb = new WebBase(pageContext);
	String uid 			  = request.getHeader("uid");//
	String id	 		  = request.getHeader("id");//
	String pid	 		  = request.getHeader("pid");
	String pidRoot		  = request.getHeader("pidRoot");
	String perSvr 		  = request.getHeader("perSvr");
	String lenSvr		  = request.getHeader("lenSvr");
	String lenLoc		  = request.getHeader("lenLoc");
	String nameLoc		  = request.getHeader("nameLoc");
	String sizeLoc		  = request.getHeader("sizeLoc");
	int blockSizeCry	  = wb.headInt("blockSizeCry");//加密块大小
	int blockSizeCpr	  = wb.headInt("blockSizeCpr");
	boolean blockEncrypt  = StringUtils.equalsIgnoreCase(request.getHeader("blockEncrypt"),"true");//是否加密
	long blockOffset 	  = Long.parseLong(request.getHeader("blockOffset"));// 	= request.getParameter("RangePos");
	int blockIndex	  	  = request.getIntHeader("blockIndex");//块偏移，基于1，相对于文件
	int blockCount	  	  = request.getIntHeader("blockCount");//块总数
	int blockSize	  	  = request.getIntHeader("blockSize");//块大小
	int blockSizeLogic 	  = request.getIntHeader("blockSizeLogic");//逻辑块大小（定义的块大小）
	String blockMd5 	  = request.getHeader("blockMd5");//文件块MD5值
	boolean blockCompress = StringUtils.equalsIgnoreCase(request.getHeader("blockCompress"),"true");;
	String blockCompressType = wb.headStr("blockCompressType");
	String encryptAlgorithm  = wb.headStr("blockEncryptAgo");//
	boolean complete	  = StringUtils.equalsIgnoreCase(request.getHeader("complete"),"true");
	String object_id   	  = request.getHeader("object_id");//
	String token		  = request.getHeader("token");
	String pathLoc		  = "";
	String pathSvr		  = "";
	String pathRel		  = "";

	//参数为空
	if ( 	StringUtils.isBlank( lenLoc )
		|| 	StringUtils.isBlank( uid )
		|| 	StringUtils.isBlank( id )
		||	StringUtils.isBlank( nameLoc ))
	{
		JSONObject o = new JSONObject();
		o.put("lenLoc",lenLoc);
		o.put("uid",uid);
		o.put("id",id);
		o.put("nameLoc",nameLoc);
		o.put("pathLoc",pathLoc);
		o.put("pidRoot",pidRoot);
		wb.send_erro("paramEmpty",o);
		return;
	}

	HttpRequest form = new HttpRequest(pageContext);
	FileItem blockData = form.getFile("file");
	pathSvr = PathTool.url_decode(form.getString("pathSvr"));
	pathRel = PathTool.url_decode(form.getString("pathRel"));
	pathLoc = PathTool.url_decode(form.getString("pathLoc"));

	ByteArrayOutputStream ostm = StreamTool.toStream(blockData);
	blockData.delete();

	FileInf fileSvr = new FileInf();
	fileSvr.id = id;
	fileSvr.pid = pid;
	fileSvr.pidRoot = pidRoot;
	fileSvr.object_id = object_id;
	fileSvr.encryptAlgorithm = encryptAlgorithm;
	fileSvr.lenSvr = Long.parseLong(lenSvr);
	fileSvr.lenLoc = Long.parseLong(lenLoc);
	fileSvr.sizeLoc = PathTool.BytesToString(fileSvr.lenLoc);
	fileSvr.pathLoc = pathLoc;
	fileSvr.pathSvr = pathSvr;
	fileSvr.pathRel = pathRel;
	fileSvr.perSvr="100%";
	fileSvr.complete = complete;
	fileSvr.blockIndex = blockIndex;
	fileSvr.blockOffset = blockOffset;
	fileSvr.blockSize = blockSize;//原始块大小
	fileSvr.blockCompress = blockCompress;
    fileSvr.blockCompressType = blockCompressType;
    fileSvr.blockEncrypt = blockEncrypt;
    fileSvr.blockSizeCry = blockSizeCry;
    fileSvr.blockSizeCpr = blockSizeCpr;
	fileSvr.blockCount = blockCount;
	fileSvr.nameLoc = PathTool.getName(pathLoc);
	fileSvr.nameSvr = fileSvr.nameLoc;
	fileSvr.encrypt= ConfigReader.storageEncrypt();//存储加密

	//验证文件块MD5
	if(!StringUtils.isBlank(blockMd5))
	{
		String md5Svr = Md5Tool.fileToMD5(ostm);
		if(!md5Svr.equals(blockMd5))
		{
			JSONObject o = new JSONObject();
			o.put("fileSvr",JSONObject.fromObject(fileSvr));
			o.put("md5Svr",md5Svr);
			o.put("md5Loc",blockMd5);
			wb.send_erro("blockMd5ValidFail",o);
			return;
		}
	}

	//块压缩
    if (fileSvr.blockCompress)
    {
        if (fileSvr.blockSizeCpr != ostm.size())
        {
            JSONObject o = new JSONObject();
            o.put("CompressSizeLoc",fileSvr.blockSizeCpr);
            o.put("CompressSizeSvr",ostm.size());
            wb.send_erro("blockSizeCprDifferent",o);
            return;
        }
        ostm = UtilsTool.unCompress(ostm,fileSvr.blockCompressType);
    }
	//传输加密
	if (fileSvr.blockEncrypt)
	{
		//接收块大小不相同
		if(fileSvr.blockSizeCry!= ostm.size())
		{
			JSONObject o = new JSONObject();
			o.put("blockSizeSend",fileSvr.blockSizeCry);
			o.put("blockSizeRecv",ostm.size());
			wb.send_erro("blockSizeCryDifferent",o);
			return;
		}

		CryptoTool ct   = new CryptoTool();
		//加密存储？
		if(!fileSvr.encrypt) ostm = ct.decrypt(fileSvr.encryptAlgorithm,ostm,fileSvr.blockSize);
	}//接收块大小不相同
	else if(blockSize!= ostm.size())
	{
		JSONObject o = new JSONObject();
		o.put("blockSizeSend",blockSize);
		o.put("blockSizeRecv",ostm.size());
		wb.send_erro("blockSizeDifferent",o);
		return;
	}

	//token验证
	WebSafe ws = new WebSafe();
	if(!ws.validToken(token,fileSvr,"block"))
	{
		JSONObject o = new JSONObject();
		o.put("fileSvr",JSONObject.fromObject(fileSvr));
		o.put("token",token);
		wb.send_erro("tokenValidFail",o);
		return;
	}

	PathBuilder pb = new PathBuilder();
	fileSvr.pathSvr = pb.relToAbs(fileSvr.pathSvr);
	
	//保存块
	FileBlockWriter fw = new FileBlockWriter();
	if(fileSvr.blockIndex==1) fw.make(fileSvr);
    fw.write(fileSvr, ostm);

	//触发事件
    up7_biz_event.file_post_block(id, blockIndex);
	
	//返回信息
	JSONObject res = new JSONObject();
	res.put("msg", "ok");
	res.put("offset", blockOffset);//基于文件的块偏移位置
	if(blockIndex==1)
	{
		JSONObject fds = new JSONObject();
		fds.put("object_id",fileSvr.object_id);
		res.put("fields",fds);
	}
	out.write(res.toString());
%>